<?php
declare(strict_types=1);

namespace LhpAmis\thinkphp\Provider;

use think\file\UploadedFile as ThinkFile;
use think\exception\FileException;

/**
 * 文件处理类
 * 扩展图片处理功能
 */
class File extends ThinkFile
{
    /**
     * 判断文件是否为图片
     * @return bool
     */
    public function isImage(): bool
    {
        $mime = $this->getMime();
        return strpos($mime, 'image/') === 0;
    }

    /**
     * 将图片转换为指定格式并覆盖原文件
     * @param string $format 目标格式，支持jpeg/png/gif/webp等
     * @param int $quality 图片质量，0-100
     * @return $this
     * @throws FileException
     */
    public function convertImage(string $format = 'jpeg', int $quality = 75): self
    {
        // 检查是否为图片
        if (!$this->isImage()) {
            throw new FileException('文件不是有效的图片');
        }

        // 获取原文件路径和信息
        $originalPath = $this->getPathname();
        $dirname = $this->getPath();
        $filename = $this->getFilename();

        // 创建临时文件路径（避免转换过程中损坏原文件）
        $tempPath = $dirname . DIRECTORY_SEPARATOR . uniqid('img_conv_', true) . '.' . $format;

        // 读取原图内容
        $imageData = file_get_contents($originalPath);
        if ($imageData === false) {
            throw new FileException('无法读取图片内容');
        }

        // 创建图片资源
        $image = imagecreatefromstring($imageData);
        if ($image === false) {
            throw new FileException('无法创建图片资源');
        }

        // 根据目标格式保存到临时文件
        $success = false;
        switch (strtolower($format)) {
            case 'jpeg':
            case 'jpg':
                $success = imagejpeg($image, $tempPath, $quality);
                break;
            case 'png':
                // PNG质量处理（0-9）
                $pngQuality = min(9, max(0, (int) (($quality / 100) * 9)));
                $success = imagepng($image, $tempPath, $pngQuality);
                break;
            case 'gif':
                $success = imagegif($image, $tempPath);
                break;
            case 'webp':
                $success = imagewebp($image, $tempPath, $quality);
                break;
            default:
                imagedestroy($image);
                throw new FileException("不支持的图片格式: {$format}");
        }

        // 释放资源
        imagedestroy($image);

        if (!$success) {
            @unlink($tempPath); // 清理临时文件
            throw new FileException("无法转换图片为{$format}格式");
        }

        // 删除原文件
        if (!@unlink($originalPath)) {
            @unlink($tempPath); // 清理临时文件
            throw new FileException("无法删除原图片文件");
        }

        // 重命名临时文件为原文件名（包含新格式）
        $newFilename = pathinfo($filename, PATHINFO_FILENAME) . '.' . $format;
        $newPath = $dirname . DIRECTORY_SEPARATOR . $newFilename;

        if (!@rename($tempPath, $newPath)) {
            @unlink($tempPath); // 清理临时文件
            throw new FileException("无法更新图片文件");
        }

        // 返回新的File实例（原路径但新格式）
        return new self($newPath, $this->getOriginalName());
    }
}
